using System;
using System.Collections.Generic;
using UnityEngine;
using Voodoo.Sauce.Core;
using Voodoo.Sauce.Privacy;
using mixpanel;

namespace Voodoo.Sauce.Internal.Analytics
{
	internal static class MixpanelWrapper
	{
		public const string TAG = "MixpanelWrapper";

		private static bool _isInitialized;

		private static bool _isDisabled;

		private static readonly Queue<MixpanelEvent> QueuedEvents = new Queue<MixpanelEvent>();

		public static void Initialize(string mixpanelToken, PrivacyCore.GdprConsent consent)
		{
			Instantiate(mixpanelToken);
			_isInitialized = true;
			SetConsent(consent.ExplicitConsentGivenForAnalytics);
			VoodooLog.LogDebug(Module.ANALYTICS, "MixpanelWrapper", "Mixpanel initialized, tracking pending events: " + QueuedEvents.Count);
			while (QueuedEvents.Count > 0)
			{
				QueuedEvents.Dequeue().Track();
			}
		}

		public static void TrackEvent(string eventName, Dictionary<string, object> eventProperties = null)
		{
			if (!_isDisabled)
			{
				Value valuesFromProperties = GetValuesFromProperties(eventProperties);
				valuesFromProperties["InternetReachability"] = Application.internetReachability.ToString();
				CustomMixpanelEvent customMixpanelEvent = new CustomMixpanelEvent(eventName, valuesFromProperties);
				if (!_isInitialized)
				{
					VoodooLog.LogDebug(Module.ANALYTICS, "MixpanelWrapper", "Mixpanel NOT initialized queuing event..." + eventName);
					QueuedEvents.Enqueue(customMixpanelEvent);
				}
				else
				{
					VoodooLog.LogDebug(Module.ANALYTICS, "MixpanelWrapper", "Sending event " + eventName + " to Mixpanel");
					customMixpanelEvent.Track();
				}
			}
		}

		public static void TrackTimedEvent(string eventName)
		{
			if (!_isDisabled)
			{
				CustomMixpanelTimedEvent customMixpanelTimedEvent = new CustomMixpanelTimedEvent(eventName);
				if (!_isInitialized)
				{
					VoodooLog.LogDebug(Module.ANALYTICS, "MixpanelWrapper", "Mixpanel NOT initialized queuing event..." + eventName);
					QueuedEvents.Enqueue(customMixpanelTimedEvent);
				}
				else
				{
					VoodooLog.LogDebug(Module.ANALYTICS, "MixpanelWrapper", "Sending timed event " + eventName + " to Mixpanel");
					customMixpanelTimedEvent.Track();
				}
			}
		}

		private static void SetConsent(bool consent)
		{
			if (!_isDisabled && _isInitialized)
			{
				VoodooLog.LogDebug(Module.ANALYTICS, "MixpanelWrapper", $"Sending  consent {consent} to Mixpanel");
				if (consent)
				{
					Mixpanel.People.Set("IDFA", VoodooSauceCore.GetPrivacy().GetAdvertisingId());
					Mixpanel.People.Set("Device Uniquer Identifier", SystemInfo.deviceUniqueIdentifier);
					Mixpanel.OptInTracking();
				}
				else
				{
					Mixpanel.OptOutTracking();
				}
			}
		}

		private static void Instantiate(string mixpanelToken)
		{
			VoodooLog.LogDebug(Module.ANALYTICS, "MixpanelWrapper", "Initializing Mixpanel");
			Mixpanel.Init();
			Mixpanel.SetToken(mixpanelToken);
			if (AnalyticsStorageHelper.Instance.IsFirstAppLaunch() || AbTestManager.IsDebugModeForced())
			{
				RegisterMixpanelSuperProperties();
			}
		}

		public static void Disable()
		{
			_isDisabled = true;
			VoodooLog.LogDebug(Module.ANALYTICS, "MixpanelWrapper", "Disabling Mixpanel");
			QueuedEvents.Clear();
		}

		private static void RegisterMixpanelSuperProperties()
		{
			VoodooLog.LogDebug(Module.ANALYTICS, "MixpanelWrapper", "Registering Mixpanel Super Properties");
			Mixpanel.Register("AB Test", AbTestManager.GetPlayerCohort());
			Mixpanel.Register("First Time App Version", Application.version);
			Mixpanel.Register("OS Type", GetPlatform());
			Mixpanel.Register("Game Bundle Id", Application.identifier);
			Mixpanel.Register("Creation Date", DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss"));
		}

		private static Value GetValuesFromProperties(Dictionary<string, object> eventProperties)
		{
			Value value = new Value();
			if (eventProperties != null)
			{
				foreach (string key in eventProperties.Keys)
				{
					if (eventProperties[key] is int)
					{
						value[key] = (int)eventProperties[key];
					}
					else if (eventProperties[key] is string)
					{
						value[key] = (string)eventProperties[key];
					}
					else if (eventProperties[key] is float)
					{
						value[key] = (float)eventProperties[key];
					}
					else if (eventProperties[key] is bool)
					{
						value[key] = (bool)eventProperties[key];
					}
					else
					{
						VoodooLog.LogWarning(Module.ANALYTICS, "MixpanelWrapper", "Ignoring unsupported event property type for key \"" + key + "\"!");
					}
				}
			}
			return value;
		}

		private static string GetPlatform()
		{
			return "Unknown";
		}
	}
}
